home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- Module name: colour naming scheme.
-
- Author: W.T. Hewitt.
-
- Function: provides an English-based interface for defining colour values.
-
- Internal function list: ptk_huev, ptk_litv, ptk_satv, ptk_vsh,
- ptk_split, ptk_cpack, ptk_cunpack, ptk_cnp, ptk_rgbv.
-
- External function list: ptk_hsltorgb, ptk_rgbtohsl, ptk_hsvtorgb,
- ptk_rgbtohsv, ptk_cnstorgb, ptk_setcnsdefaults, ptk_inqcnsdefaults.
-
- Hashtables used: "colourindex".
-
- Modification history: (Version), (Date), (Name), (Description).
-
- 1.0, ?????, W.T. Hewitt, First version.
-
- 2.0, 8th April 1991, J.G. Williams, Converted from FORTRAN to C.
-
- 3.0, June 1992, G. Williams, Converted to ISO PHIGS C.
-
- ----------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <math.h>
- #include <ctype.h>
- #include <phigs.h>
- #include "ptk.h"
-
- /*--------------------------------------------------------------------------*/
-
- #define ILOFF 0
- #define ILLEN 5
- #define ISOFF 5
- #define ISLEN 4
- #define IHOFF 9
- #define IHLEN 44
-
- /*--------------------------------------------------------------------------*/
-
- static char *colwrd[] =
- {
- "VERY-DARK","DARK","MEDIUM","LIGHT","VERY-LIGHT",
- "GREYISH","MODERATE","STRONG","VIVID",
- "RED","ORANGISH-RED", "BROWNISH-RED","ORANGE-RED",
- "RED-ORANGE","BROWN-RED","RED-BROWN", "REDDISH-ORANGE",
- "REDDISH-BROWN","ORANGE","BROWN","YELLOWISH-ORANGE",
- "YELLOWISH-BROWN","YELLOW-ORANGE","ORANGE-YELLOW",
- "YELLOW-BROWN","BROWN-YELLOW", "ORANGISH-YELLOW",
- "BROWNISH-YELLOW", "YELLOW",
- "GREENISH-YELLOW","GREEN-YELLOW","YELLOW-GREEN",
- "YELLOWISH-GREEN", "GREEN", "BLUISH-GREEN", "BLUE-GREEN",
- "GREEN-BLUE","GREENISH-BLUE", "BLUE","PURPLISH-BLUE",
- "PURPLE-BLUE","BLUE-PURPLE","BLUISH-PURPLE",
- "PURPLE","REDDISH-PURPLE","RED-PURPLE","PURPLE-RED",
- "PURPLISH-RED", "MAGENTA", "CYAN", "BLACK", "GREY", "WHITE"
- };
-
- static Pfloat vsh[44][3] =
- {
- 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.8, 0.8, 1.0, 1.0, 1.0, 2.0,
- 1.0, 1.0, 2.0, 0.8, 0.8, 2.0, 0.8, 0.8, 2.0, 1.0, 1.0, 3.0,
- 0.8, 0.8, 3.0, 1.0, 1.0, 4.0, 0.8, 0.8, 4.0, 1.0, 1.0, 5.0,
- 0.8, 0.8, 5.0, 1.0, 1.0, 6.0, 1.0, 1.0, 6.0, 0.8, 0.8, 6.0,
- 0.8, 0.8, 6.0, 1.0, 1.0, 7.0, 0.8, 0.8, 7.0, 1.0, 1.0, 8.0,
- 1.0, 1.0, 10.0, 1.0, 1.0, 12.0, 1.0, 1.0, 12.0, 1.0, 1.0, 14.0,
- 1.0, 1.0, 16.0, 1.0, 1.0, 20.0, 1.0, 1.0, 24.0, 1.0, 1.0, 24.0,
- 1.0, 1.0, 28.0, 1.0, 1.0, 32.0, 1.0, 1.0, 34.0, 1.0, 1.0, 36.0,
- 1.0, 1.0, 36.0, 1.0, 1.0, 38.0, 1.0, 1.0, 40.0, 1.0, 1.0, 42.0,
- 1.0, 1.0, 44.0, 1.0, 1.0, 44.0, 1.0, 1.0, 46.0, 1.0, 1.0, 40.0,
- 1.0, 1.0, 24.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0
- };
-
- static char *shtwrd[] =
- { "L1","L2","L3","L4","L5","S1","S2","S3","S4",
- "H/","H0","H1","H2","H3","H4","H5","H6","H7",
- "H8","H9","H*","H:","H;","H<","H=","H>","H?",
- "H@","HA","HB","HC","HD","HE","HF","HG","HI",
- "HJ","HK","HL","HM","HN","HO","HP","HQ","HR",
- "HS","HT","HU","HV","HW","HX","HY","HZ"
- };
-
- static Pint deflight = 3;
- static Pint defsat = 8;
-
- static char **rgbnames;
- static Prgb *rgbvalues;
- static Pint numrgbs = 0;
-
- /*--------------------------------------------------------------------------*/
-
- static Pint ptk_huev(C(char *) word, C(Phsv *) hsv)
- PreANSI(char *word)
- PreANSI(Phsv *hsv)
- /*
- ** \parambegin
- ** \param{}{word}{hue name (shorthand version)}{IN}
- ** \param{}{hls}{HSV triplet}{IN}
- ** return value: 0 if HSV ok, -1 if not ok.
- ** \paramend
- ** \blurb{This function returns the HSV value for hue name
- ** \pardesc{word}.}
- */
- {
- Pint ii, jj;
-
- ii = instrlist(&shtwrd[IHOFF], IHLEN, word);
-
- if (ii >= 0)
- {
- hsv->hue = vsh[ii][2]/48.0;
- hsv->satur = vsh[ii][1];
- hsv->value = vsh[ii][0];
- return 0;
- }
- else
- {
- /* call iferror(-1,'PTK_HUEV - invalid Hue name') */
- return -1;
- }
- } /* ptk_huev */
-
- /*--------------------------------------------------------------------------*/
-
- static Pint ptk_litv(C(char *) word, C(Phsv *) hsv)
- PreANSI(char *word)
- PreANSI(Phsv *hsv)
- /*
- ** \parambegin
- ** \param{}{word}{lightness name (shorthand version)}{IN}
- ** \param{}{hls}{HSV value}{IN}
- ** return value: 0 if HSV ok, -1 if not ok.
- ** \paramend
- ** \blurb{This function returns the HSV value for lightness \pardesc{name}.}
- */
- {
- Pint ii, jj;
-
- ii = instrlist(&shtwrd[ILOFF], ILLEN, word);
-
- if (ii >= 0)
- {
- hsv->value = hsv->value * ((Pfloat)(ii + 1)/5.0);
- return 0;
- }
- else
- {
- /* call iferror(-1,'PTK_LITV - invalid lightness name') */
- return -1;
- }
- }
-
- /*--------------------------------------------------------------------------*/
-
- static Pint ptk_satv(C(char *) word, C(Phsv *) hsv)
- PreANSI(char *word)
- PreANSI(Phsv *hsv)
- /*
- ** \parambegin
- ** \param{}{word}{saturation name (shorthand version)}{IN}
- ** \param{}{hls}{HSV value}{IN}
- ** return value: 0 if HSV ok, -1 if not ok.
- ** \paramend
- ** \blurb{This function Return HSV value for saturation name.}
- */
- {
- Pint ii, jj;
-
- ii = instrlist(&shtwrd[ISOFF], ISLEN, word);
-
- if (ii >= 0)
- {
- hsv->satur = hsv->satur * 0.25 * (Pfloat)(ii + 1);
- return 0;
- }
- else
- {
- /* call iferror(-1,'PTK_SATV - invalid Saturation name') */
- return -1;
- }
- }
-
- /*--------------------------------------------------------------------------*/
-
- static Pint ptk_vsh(C(char *) word1, C(char *) word2, C(char *) word3,
- C(Phsv *) hsv)
- PreANSI(char *word1)
- PreANSI(char *word2)
- PreANSI(char *word3)
- PreANSI(Phsv *hsv)
- /*
- ** \parambegin
- ** \param{}{word1}{lightness name}{IN}
- ** \param{}{word2}{saturation name}{IN}
- ** \param{}{word3}{hue name}{IN}
- ** \param{}{hls}{HSV triplet}{IN}
- ** return value: 0 if HSV ok, -1 if not ok.
- ** \paramend
- ** \blurb{This function Return HSV value for hue, saturation and lightness names.}
- */
- {
- Pint fvsh;
-
- fvsh = ptk_huev(word3, hsv);
- if (fvsh == 0)
- {
- if ((strncmp(word3, "HX", 2) != 0)
- && (strncmp(word3, "HZ", 2) != 0))
- {
- fvsh = ptk_litv(word1, hsv);
- if ((fvsh == 0) && (strncmp(word2, "HY", 2) != 0))
- fvsh = ptk_satv(word2, hsv);
- }
- }
- return fvsh;
- }
-
- /*--------------------------------------------------------------------------*/
-
- static void ptk_split(C(char *) linein, C(char *) lineout, C(Pint *) iword)
- PreANSI(char *linein)
- PreANSI(char *lineout)
- PreANSI(Pint *iword)
- /*
- ** \parambegin
- ** \param{}{linein}{line to split}{IN}
- ** \param{}{lineout}{split line}{IN}
- ** \param{}{iword}{number of words in line}{IN}
- ** \paramend
- ** \blurb{This function Removes leadings spaces, collapses multiple spaces to single
- ** spaces and counts the number of words.}
- */
- {
- Pint ii, jj, ll;
- char lastchar;
-
- *iword = 0;
-
- jj = strlen(linein);
-
- if (jj == 0)
- return;
-
- *iword = 1;
- ll = -1;
- lastchar = ' ';
- for (ii = 0; ii <= jj; ii++)
- {
- if (linein[ii] != ' ')
- {
- ll++;
- lineout[ll] = linein[ii];
- lastchar = lineout[ll];
- }
- else
- if (lastchar != ' ')
- {
- (*iword)++;
- ll++;
- lineout[ll] = ' ';
- lastchar = ' ';
- }
- }
- lineout[jj + 1] = '\0';
- }
-
- /*--------------------------------------------------------------------------*/
-
- static Pint ptk_cpack(C(char *) line, C(char *) pline)
- PreANSI(char *line)
- PreANSI(char *pline)
- /*
- ** \parambegin
- ** \param{}{line}{longhand colour description}{IN}
- ** \param{}{pline}{shorthand colour description}{IN}
- ** return value: 0 if ok, -1 if not ok.
- ** \paramend
- ** \blurb{This function Pack a colour description into 6 characters.}
- */
- {
- Pint fcpk;
- Pint r, g, b;
-
- fcpk = ptk_cnp(line, pline, colwrd, shtwrd, 0);
- return fcpk;
- }
-
- /*--------------------------------------------------------------------------*/
-
- static Pint ptk_cnp(C(char *) line, C(char *) pline, C(char **) inwrd,
- C(char **) otwrd)
- PreANSI(char *line)
- PreANSI(char *pline)
- PreANSI(char **inwrd)
- PreANSI(char **otwrd)
- /*
- ** \parambegin
- ** \param{}{line}{longhand colour description}{IN}
- ** \param{}{pline}{shorthand colour description}{IN}
- ** \param{}{inwrd}{pointer to longhand string list}{IN}
- ** \param{}{outwrd}{pointer to shorthand string list}{IN}
- ** \param{}{gap}{number of spaces between strings}{IN}
- ** \paramend
- ** \blurb{This function Translate words.
- ** Returns 0 if ok, -1 if not ok.}
- */
- {
- char lline[60];
- char word[20];
- Pint ii, iword, iend, ist, jj, ll;
- Pint fcnp;
- char tempstr[255];
-
- /* Split etc into words */
-
- ptk_split(line, lline, &iword);
-
- strupper(lline);
-
- ll = 0;
- ist = 0;
- fcnp = 0;
-
- /* Copy words */
-
- for (ii = 0; ii < iword; ii++)
- {
- iend = stringlength(&lline[ist]) + ist;
-
- strncpy(word, &lline[ist], iend - ist);
- word[iend - ist] = '\0';
-
- strncpy(tempstr, word, (iend - ist + 1));
-
- jj = instrlist(inwrd, 53, tempstr);
-
- if (jj >= 0)
- {
- strncpy(&pline[ll], otwrd[jj], 2);
- ll = ll + 2;
- }
- else
- {
- strncpy(&pline[ll], word, (iend-ist));
- ll = ll + iend - ist;
- fcnp = -1;
- }
- ist = iend + 1;
- }
- pline[ll] = '\0';
- return fcnp;
- }
-
- /*--------------------------------------------------------------------------*/
-
- static Pfloat ptk_rgbv(C(Pfloat) m1, C(Pfloat) m2, C(Pfloat) h)
- PreANSI(Pfloat m1)
- PreANSI(Pfloat m2)
- PreANSI(Pfloat h)
- /*
- ** \parambegin
- ** \param{}{m1, m2}{real numbers}{IN}
- ** \param{}{h}{hue value}{IN}
- ** \paramend
- ** \blurb{This function Return R, G or B value given 3 real numbers.
- ** Returns R, G, or B value.}
- */
- {
- Pfloat const1,const2;
- Pfloat frgbv;
-
- const1 = 1.0/6.0;
- const2 = 2.0/3.0;
-
- if (h > 1.0)
- h = h - 1.0;
- if (h < 0.0)
- h = h + 1.0;
-
- if (h < const1)
- frgbv = m1 + ((m2 - m1) * h * 6.0);
- else
- if (h < 0.5)
- frgbv = m2;
- else
- if (h < const2)
- frgbv = m1 + ((m2 - m1) * (const2 - h) * 6.0);
- else
- frgbv = m1;
-
- return frgbv;
- }
-
- /*--------------------------------------------------------------------------*/
-
- static void ptk_realtocobundl(C(Pfloat *) reals, C(Prgb *) col,
- C(Pint) model)
- PreANSI(Pfloat reals[3])
- PreANSI(Prgb *col)
- PreANSI(Pint model)
- {
- col->red = reals[0];
- col->green = reals[1];
- col->blue = reals[2];
- }
-
- /*--------------------------------------------------------------------------*/
-
- static void ptk_cobundltoreal(C(Pfloat *) reals, C(Prgb *) col,
- C(Pint) model)
- PreANSI(Pfloat reals[3])
- PreANSI(Prgb *col)
- PreANSI(Pint model)
- {
- reals[0] = col->red;
- reals[1] = col->green;
- reals[2] = col->blue;
- }
-
- /*--------------------------------------------------------------------------*/
-
- static void convertcolourname(C(char *) colourname, C(Prgb *) rgb,
- C(Pint *) err)
- PreANSI(char *colourname)
- PreANSI(Prgb *rgb)
- PreANSI(Pint *err)
- /*
- ** \parambegin
- ** \param{}{colourname}{colour description}{IN}
- ** \param{}{rgb}{RGB triplet}{IN}
- ** \paramend
- ** \blurb{This function Converts longhand colour description to RGB->
- ** Returns TRUE if ok, FALSE if not ok.}
- */
- {
- char lpack[7];
- Phsv hsv;
- Pint ii, iword, r, g, b;
- char word[3][3];
- Pint fcns;
- Pfloat argb[3];
-
- *err = 0;
- /* pack into internal format */
- fcns = ptk_cpack(colourname, lpack);
- if (fcns == 0)
- {
- iword = stringlength(lpack);
- iword = (Pint)iword/2;
- if (iword == 0)
- {
- /* blank line */
- *err = 1;
- return;
- }
-
- /* Iword should be 1,2 or 3 */
- /*
- ** Iword = 1 => HUE only
- ** Iword = 2 => Lightness hue or saturation hue
- ** Iword = 3 => Lightness sat hue or sat light hue
- ** (HUE is ALWAYS last)
- */
-
- /* extract separate words */
-
- for (ii = 0; ii < iword; ii++)
- {
- strncpy(word[ii], &lpack[2 * ii], 2);
- word[ii][2] = '\0';
- }
-
- /*
- ** light = 'L4'
- ** vivid = 'S4'
- */
-
- if (iword == 1)
- fcns = ptk_vsh(shtwrd[deflight], shtwrd[defsat], word[0], &hsv);
- else
- if (iword == 2)
- {
- if (ptk_litv(word[0], &hsv) == 0)
- fcns = ptk_vsh(word[0], shtwrd[defsat], word[1], &hsv);
- else
- fcns = ptk_vsh(shtwrd[deflight], word[0], word[1], &hsv);
- }
- else
- {
- if (ptk_litv(word[0], &hsv) == 0)
- fcns = ptk_vsh(word[0], word[1], word[2], &hsv);
- else
- fcns = ptk_vsh(word[1], word[0], word[2], &hsv);
- }
- }
-
- if (fcns == 0)
- {
- ptk_hsvtorgb(&hsv, rgb);
- return;
- }
- else
- {
- /* try rgb colour names */
- ii = instrlist(rgbnames, numrgbs, colourname);
- if (ii >= 0)
- {
- *rgb = rgbvalues[ii];
- *err = 2;
- return;
- }
- }
- /* failed to convert colour, using white */
- argb[0] = 1.0;
- argb[1] = 1.0;
- argb[2] = 1.0;
- ptk_realtocobundl(argb, rgb, 1);
- *err = 3;
- } /* convertcolourname */
-
- /*--------------------------------------------------------------------------*/
-
- static void setcolourrep(C(Pint) wsid, C(char *) colourname,
- C(Pint *) cindex)
- PreANSI(Pint wsid)
- PreANSI(char *colourname)
- PreANSI(Pint *cindex)
- {
- Pcolr_rep rgb;
- Pint err;
-
- convertcolourname(colourname, &rgb, &err);
- if ((err == 0) || (err == 2))
- {
- *cindex = ptk_stringtoint("colourindex", colourname);
- pset_colr_rep(wsid, *cindex, &rgb);
- }
- else
- *cindex = -1;
- } /* setcolourrep */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_hsltorgb(C(Phls *) hsl, C(Prgb *) rgb)
- PreANSI(Phls *hsl)
- PreANSI(Prgb *rgb)
- /*
- ** \parambegin
- ** \param{Phls *}{hsl}{HSL triplet}{IN}
- ** \param{Prgb *}{rgb}{RGB triplet}{IN}
- ** \paramend
- ** \blurb{This function converts from the HSL double-ended hexcone
- ** model to the
- ** RGB model. Given HSL, the equivalent RGB parameters are computed.
- ** All parameters are assumed to be in the range 0.0 to 1.0. The
- ** algorithm is adapted from~\cite{foley:fic}.}
- */
- {
- Pfloat value, m1, m2;
- Pfloat ahsl[3], argb[3];
-
- value = 1.0/3.0;
-
- ptk_cobundltoreal(ahsl, hsl, 2);
- if (ahsl[2] <= 0.5)
- m2 = ahsl[2] * (1.0 + ahsl[1]);
- else
- m2 = ahsl[2] + ahsl[1] - (ahsl[2] * ahsl[1]);
-
- m1 = 2.0 * ahsl[2] - m2;
- if (ahsl[1] == 0.0)
- {
- argb[0] = ahsl[2];
- argb[1] = ahsl[2];
- argb[2] = ahsl[2];
- }
- else
- {
- argb[0] = ptk_rgbv(m1, m2, ahsl[0] + value);
- argb[1] = ptk_rgbv(m1, m2, ahsl[0]);
- argb[2] = ptk_rgbv(m1, m2, ahsl[0] - value);
- }
- ptk_realtocobundl(argb, rgb, 1);
- } /* ptk_hsltorgb */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_rgbtohsl(C(Prgb *) rgb, C(Phls *) hsl)
- PreANSI(Prgb *rgb)
- PreANSI(Phls *hsl)
- /*
- ** \parambegin
- ** \param{Prgb *}{rgb}{RGB triplet}{IN}
- ** \param{Phls *}{hsl}{HSL triplet}{IN}
- ** \paramend
- ** \blurb{This function converts an RGB triplet to a HSL triplet.
- ** The
- ** algorithm is adapted from~\cite{watt:fotdcg}.}
- */
- {
- Pfloat maxval, minval, diff, rdist, gdist, bdist;
- Pfloat ahsl[3], argb[3];
-
- ptk_cobundltoreal(argb, rgb, 1);
- maxval = PTKMAX(argb[0], argb[1]);
- maxval = PTKMAX(maxval, argb[2]);
- minval = PTKMIN(argb[0], argb[1]);
- minval = PTKMIN(minval, argb[2]);
- diff = maxval - minval;
- ahsl[2] = (maxval + minval) / 2.0;
- if (abs(diff) < 0.00001)
- {
- ahsl[1] = 0.0;
- ahsl[0] = 0.0; /* undefined */
- }
- else
- {
- if (ahsl[2] <= 0.5)
- ahsl[1] = diff / (maxval + minval);
- else
- ahsl[1] = diff / (2.0 - maxval - minval);
- rdist = (maxval - argb[0])/diff;
- gdist = (maxval - argb[1])/diff;
- bdist = (maxval - argb[2])/diff;
- if (argb[0] == maxval)
- ahsl[0] = bdist - gdist;
- else
- if (argb[1] == maxval)
- ahsl[0] = 2.0 + rdist - bdist;
- else
- if (argb[2] == maxval)
- ahsl[0] = 4.0 + gdist - rdist;
- ahsl[0] *= 60.0;
- if (ahsl[0] < 0.0)
- ahsl[0] += 360.0;
- }
- ptk_realtocobundl(ahsl, hsl, 2);
- } /* ptk_rgbtohsl */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_hsvtorgb(C(Phsv *) hsv, C(Prgb *) rgb)
- PreANSI(Phsv *hsv)
- PreANSI(Prgb *rgb)
- /*
- ** \parambegin
- ** \param{Phsv *}{hsv}{HSV triplet}{IN}
- ** \param{Prgb *}{rgb}{RGB triplet}{IN}
- ** \paramend
- ** \blurb{This function converts a HSV triplet to a RGB triplet.
- ** The
- ** algorithm is adapted from~\cite{watt:fotdcg}.}
- */
- {
- Pfloat f, p, q, t;
- Pint i;
- Pfloat ahsv[3], argb[3];
-
- ptk_cobundltoreal(ahsv, hsv, 3);
- if (ahsv[1] == 0.0)
- {
- argb[0] = ahsv[2];
- argb[1] = ahsv[2];
- argb[2] = ahsv[2];
- }
- else
- {
- if (ahsv[0] == 1.0)
- ahsv[0] = 0.0;
- ahsv[0] *= 6.0;
- i = floor(ahsv[0]);
- f = ahsv[0] - (Pfloat)i;
- p = ahsv[2] * (1.0 - ahsv[1]);
- q = ahsv[2] * (1.0 - (ahsv[1] * f));
- t = ahsv[2] * (1.0 - (ahsv[1] * (1.0 - f)));
- switch (i)
- {
- case 0: argb[0] = ahsv[2];
- argb[1] = t;
- argb[2] = p;
- break;
- case 1: argb[0] = q;
- argb[1] = ahsv[2];
- argb[2] = p;
- break;
- case 2: argb[0] = p;
- argb[1] = ahsv[2];
- argb[2] = t;
- break;
- case 3: argb[0] = p;
- argb[1] = q;
- argb[2] = ahsv[2];
- break;
- case 4: argb[0] = t;
- argb[1] = p;
- argb[2] = ahsv[2];
- break;
- case 5: argb[0] = ahsv[2];
- argb[1] = p;
- argb[2] = q;
- break;
- }
- }
- ptk_realtocobundl(argb, rgb, 1);
- } /* ptk_hsvtorgb */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_rgbtohsv(C(Prgb *) rgb, C(Phsv *) hsv)
- PreANSI(Prgb *rgb)
- PreANSI(Phsv *hsv)
- /*
- ** \parambegin
- ** \param{Prgb *}{rgb}{RGB triplet}{IN}
- ** \param{Phsv *}{hsv}{HSV triplet}{IN}
- ** \paramend
- ** \blurb{This function converts an RGB value to a HSV value.
- ** The
- ** algorithm is adapted from~\cite{watt:fotdcg}.}
- */
- {
- Pfloat maxval, minval, diff, rdist, gdist, bdist;
- Pfloat ahsv[3], argb[3];
-
- ptk_cobundltoreal(argb, rgb, 1);
- maxval = PTKMAX(argb[0], argb[1]);
- maxval = PTKMAX(maxval, argb[2]);
- minval = PTKMIN(argb[0], argb[1]);
- minval = PTKMIN(minval, argb[2]);
- diff = maxval - minval;
- ahsv[2] = maxval;
- if (maxval != 0.0)
- ahsv[1] = diff/maxval;
- else
- ahsv[1] = 0.0;
- if (ahsv[1] == 0.0)
- ahsv[0] = 0.0; /* undefined */
- else
- {
- rdist = (maxval - argb[0])/diff;
- gdist = (maxval - argb[1])/diff;
- bdist = (maxval - argb[2])/diff;
- if (argb[0] == maxval)
- ahsv[0] = bdist - gdist;
- else
- if (argb[1] == maxval)
- ahsv[0] = 2.0 + rdist - bdist;
- else
- if (argb[2] == maxval)
- ahsv[0] = 4.0 + gdist - rdist;
- ahsv[0] *= 60.0;
- if (ahsv[0] < 0.0)
- ahsv[0] += 360.0;
- }
- ptk_realtocobundl(ahsv, hsv, 3);
- } /* ptk_rgbtohsv */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern ptkboolean ptk_cnstorgb(C(char *) colourname, C(Prgb *) rgb)
- PreANSI(char *colourname)
- PreANSI(Prgb *rgb)
- /*
- ** \parambegin
- ** \param{char *}{colourname}{colour description}{IN}
- ** \param{Prgb *}{rgb}{RGB triplet}{IN}
- ** \paramend
- ** \blurb{This function converts a CNS colour name to the equivalent
- ** RGB value, returning TRUE if the conversion was successful,
- ** and FALSE if not.}
- */
- {
- Pint err;
-
- convertcolourname(colourname, rgb, &err);
- if ((err == 0) || (err == 2))
- return TRUE;
- else
- {
- return FALSE;
- }
- } /* ptk_cnstorgb */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern ptkboolean ptk_cnstohsl(C(char *) colourname, C(Phls *) hsl)
- PreANSI(char *colourname)
- PreANSI(Phls *hsl)
- /*
- ** \parambegin
- ** \param{char *}{colourname}{colour description}{IN}
- ** \param{Phls *}{hsl}{HSL triplet}{IN}
- ** \paramend
- ** \blurb{This function converts a CNS colour name to the equivalent
- ** HSL value, returning TRUE if the conversion was successful,
- ** and FALSE if not.}
- */
- {
- Prgb rgb;
-
- if (ptk_cnstorgb(colourname, &rgb))
- {
- ptk_rgbtohsl(&rgb, hsl);
- return TRUE;
- }
- else
- return FALSE;
- } /* ptk_cnstohsl */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern ptkboolean ptk_cnstohsv(C(char *) colourname, C(Phsv *) hsv)
- PreANSI(char *colourname)
- PreANSI(Phsv *hsv)
- /*
- ** \parambegin
- ** \param{char *}{colourname}{colour description}{IN}
- ** \param{Phsv *}{hsv}{HSV triplet}{IN}
- ** \paramend
- ** \blurb{This function Converts colour name to HSV.
- ** Returns TRUE if ok, FALSE if not ok.}
- */
- {
- Prgb rgb;
-
- if (ptk_cnstorgb(colourname, &rgb))
- {
- ptk_rgbtohsv(&rgb, hsv);
- return TRUE;
- }
- else
- return FALSE;
- } /* ptk_cnstohsv */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setcnsdefaults(C(ptkelightness) lightness,
- C(ptkesaturation) saturation)
- PreANSI(ptkelightness lightness)
- PreANSI(ptkesaturation saturation)
- /*
- ** \parambegin
- ** \param{ptkelightness}{lightness}{default lightness for colours}{IN}
- ** \param{ptkesaturation}{saturation}{default saturation for colours}{IN}
- ** \paramend
- ** \blurb{This function sets default values for lightness and
- ** saturation for the Colour Naming
- ** Scheme. If lightness or saturation is missing when a
- ** colour name is subsequently specified, the
- ** default is used.}
- */
- {
- if ((lightness >= 0) && (lightness <= 4))
- deflight = lightness;
- if ((saturation >= 0) && (saturation <= 3))
- defsat = saturation + 5;
- } /* ptk_setcnsdefaults */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_inqcnsdefaults(C(ptkelightness *) lightness,
- C(ptkesaturation *) saturation)
- PreANSI(ptkelightness *lightness)
- PreANSI(ptkesaturation *saturation)
- /*
- ** \parambegin
- ** \param{ptkelightness *}{lightness}{default lightness for colours}{OUT}
- ** \param{ptkesaturation *}{saturation}{default saturation for colours}{OUT}
- ** \paramend
- ** \blurb{This function inquires the
- ** default values of lightness and saturation used in the Colour
- ** Naming Scheme.}
- */
- {
- *lightness = deflight;
- *saturation = defsat - 5;
- } /* ptk_inqcnsdefaults */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setupcolourtable(C(Pint) wsid, C(Pint) num,
- C(char **) colournames)
- PreANSI(Pint wsid)
- PreANSI(Pint num)
- PreANSI(char **colournames)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{Pint}{num}{number of colour names}{IN}
- ** \param{char **}{colournames}{list of colour names}{IN}
- ** \paramend
- ** \blurb{This function sets colour representations in
- ** the colour table of workstation \pardesc{wsid},
- ** using the list of colour names \pardesc{colournames}.
- ** The hashstrings table
- ** {\tt "colourindex"} is used to derive the index to the colour table.}
- */
- {
- Pint i;
- Pcolr_rep rep;
-
- for (i = 0; i < num; i++)
- {
- if (ptk_cnstorgb(colournames[i], &rep.rgb))
- pset_colr_rep(wsid, ptk_stringtoint("colourindex", colournames[i]),
- &rep);
- }
- } /* ptk_setupcolourtable */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setcolourrep(C(Pint) wsid, C(char *) colourname)
- PreANSI(Pint wsid)
- PreANSI(char *colourname)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{char *}{colourname}{colour name}{IN}
- ** \paramend
- ** \blurb{This function sets colour representations in
- ** the colour table of workstation \pardesc{wsid},
- ** using the colour name \pardesc{colourname}.
- ** The hashstrings table
- ** {\tt "colourindex"} is used to derive the index to the colour table.}
- */
- {
- Pcolr_rep rep;
-
- if (ptk_cnstorgb(colourname, &rep.rgb))
- pset_colr_rep(wsid, ptk_stringtoint("colourindex", colourname), &rep);
- } /* ptk_setcolourrep */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setrgbcolourname(C(char *) colourname, C(Prgb *) rgb)
- PreANSI(char *colourname)
- PreANSI(Prgb *rgb)
- /*
- ** \parambegin
- ** \param{char *}{colourname}{colour name}{IN}
- ** \param{Prgb *}{rgb}{RGB colour value}{IN}
- ** \paramend
- ** \blurb{This function sets a colour representation in
- ** CNS using the colour name and
- ** RGB value. The colour name must be different to the names provided by
- ** the CNS. This function enables additional names for colours to
- ** be specified in addition to those provided by CNS.}
- */
- {
- Pint err, ii;
- Prgb temp;
-
- convertcolourname(colourname, &temp, &err);
- switch (err)
- {
- case 0: /* colourname is part of the colour naming scheme */
- fprintf(stderr, "ptk_setrgbcolourname: sorry, colourname \"%s\" is part of the colour naming scheme\n", colourname);
- break;
-
- case 1: /* blank line */
- fprintf(stderr, "ptk_setrgbcolourname: sorry, colourname \"%s\" is invalid\n", colourname);
- break;
-
- case 2: /* already defined rgb name */
- ii = instrlist(rgbnames, numrgbs, colourname);
- rgbvalues[ii] = *rgb;
- break;
-
- case 3: /* name not rgb or cns */
- numrgbs++;
- if (numrgbs == 1)
- {
- rgbnames = (char **)calloc(1, sizeof(char *));
- rgbvalues = (Prgb *)calloc(1, sizeof(Prgb));
- }
- else
- {
- rgbnames = (char **)realloc(rgbnames, numrgbs * sizeof(char *));
- rgbvalues = (Prgb *)realloc(rgbvalues, numrgbs * sizeof(Prgb));
- }
- rgbnames[numrgbs - 1] = (char *)malloc(strlen(colourname) + 1);
- strcpy(rgbnames[numrgbs - 1], colourname);
- rgbvalues[numrgbs - 1] = *rgb;
- break;
- }
- } /* ptk_setrgbcolourname */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setbackgroundcolourind(C(Pint) wsid, C(Pint) index)
- PreANSI(Pint wsid)
- PreANSI(Pint index)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{Pint}{index}{colour index}{IN}
- ** \paramend
- ** \blurb{This function sets the colour representation of the
- ** zeroth entry in the
- ** colour table of workstation \pardesc{wsid}, to be same as the
- ** entry \pardesc{index} in the colour table.}
- */
- {
- Pcolr_rep colour;
- Pint err;
-
- pinq_colr_rep(wsid, index, PINQ_REALIZED, &err, &colour);
- if (err == 0)
- pset_colr_rep(wsid, 0, &colour);
- } /* ptk_setbackgroundcolourind */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setbackgroundcolour(C(Pint) wsid, C(char *) colourname)
- PreANSI(Pint wsid)
- PreANSI(char *colourname)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{char *}{colourname}{colour name}{IN}
- ** \paramend
- ** \blurb{This function sets the colour representation of the
- ** zeroth entry in the
- ** colour table of workstation \pardesc{wsid}, to be that
- ** specified by \pardesc{colourname} in the CNS.}
- */
- {
- Pint err;
- Pcolr_rep rep;
-
- convertcolourname(colourname, &rep.rgb, &err);
- if ((err == 0) || (err == 2))
- pset_colr_rep(wsid, 0, &rep);
- } /* ptk_setbackgroundcolour */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setlinecolour(C(Pint) wsid, C(char *) colourname)
- PreANSI(Pint wsid)
- PreANSI(char *colourname)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{char *}{colourname}{colour name}{IN}
- ** \paramend
- ** \blurb{This function sets the polyline colour index to be that specified by the given
- ** colour name in the {\tt "colourindex"} hashtable. The colour representation
- ** is set in the workstation colour table if necessary.}
- */
- {
- Pint cindex;
-
- setcolourrep(wsid, colourname, &cindex);
- if (cindex != -1)
- pset_line_colr_ind(cindex);
- } /* ptk_setlinecolour */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setmarkercolour(C(Pint) wsid, C(char *) colourname)
- PreANSI(Pint wsid)
- PreANSI(char *colourname)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{char *}{colourname}{colour name}{IN}
- ** \paramend
- ** \blurb{This function sets the polymarker colour index to be that specified by the given
- ** colour name in the {\tt "colourindex"} hashtable. The colour representation
- ** is set in the workstation colour table if necessary.}
- */
- {
- Pint cindex;
-
- setcolourrep(wsid, colourname, &cindex);
- if (cindex != -1)
- pset_marker_colr_ind(cindex);
- } /* ptk_setmarkercolour */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setintcolour(C(Pint) wsid, C(char *) colourname)
- PreANSI(Pint wsid)
- PreANSI(char *colourname)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{char *}{colourname}{colour name}{IN}
- ** \paramend
- ** \blurb{This function sets the interior colour index to be that specified by the given
- ** colour name in the {\tt "colourindex"} hashtable. The colour representation
- ** is set in the workstation colour table if necessary.}
- */
- {
- Pint cindex;
-
- setcolourrep(wsid, colourname, &cindex);
- if (cindex != -1)
- pset_int_colr_ind(cindex);
- } /* ptk_setintcolour */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_setedgecolour(C(Pint) wsid, C(char *) colourname)
- PreANSI(Pint wsid)
- PreANSI(char *colourname)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{char *}{colourname}{colour name}{IN}
- ** \paramend
- ** \blurb{This function sets the edge colour index to be that specified by the given
- ** colour name in the {\tt "colourindex"} hashtable. The colour representation
- ** is set in the workstation colour table if necessary.}
- */
- {
- Pint cindex;
-
- setcolourrep(wsid, colourname, &cindex);
- if (cindex != -1)
- pset_edge_colr_ind(cindex);
- } /* ptk_setedgecolour */
-
- /*--------------------------------------------------------------------------*/
-
- /*function:external*/
- extern void ptk_settextcolour(C(Pint) wsid, C(char *) colourname)
- PreANSI(Pint wsid)
- PreANSI(char *colourname)
- /*
- ** \parambegin
- ** \param{Pint}{wsid}{workstation identifier}{IN}
- ** \param{char *}{colourname}{colour name}{IN}
- ** \param{Pint}{index}{colour index}{IN}
- ** \paramend
- ** \blurb{This function sets the text colour index to be that specified by the given
- ** colour name in the {\tt "colourindex"} hashtable. The colour representation
- ** is set in the workstation colour table if necessary.}
- */
- {
- Pint cindex;
-
- setcolourrep(wsid, colourname, &cindex);
- if (cindex != -1)
- pset_text_colr_ind(cindex);
- } /* ptk_settextcolour */
-
- /*--------------------------------------------------------------------------*/
-
- /* end of cns.c */
-